package cn.school.job.course;

import cn.hutool.core.date.DateUtil;
import cn.school.common.utils.CourseConstants;
import cn.school.course.entity.CoursePlan;
import cn.school.course.service.CourseConflictService;
import cn.school.course.service.CoursePlanConflictService;
import cn.school.course.service.CoursePlanService;
import cn.school.sys.entity.SysConfig;
import cn.school.sys.entity.TermTime;
import cn.school.sys.service.SysConfigService;
import cn.school.sys.service.TermTimeService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 课程生成JOB
 *
 * @className: course
 * @author: fangjin.tao
 * @date: 2023/1/10
 **/
public class CourseGennerJob extends QuartzJobBean {
	private static Logger log = LoggerFactory.getLogger(CourseGennerJob.class);
	/**
	 * 单例运行
	 */
	private static Boolean isGennerStatus = false;
	@Autowired
	private CoursePlanService coursePlanService;
	@Autowired
	private SysConfigService sysConfigService;
	@Autowired
	private TermTimeService termTimeService;
	@Autowired
	private CoursePlanConflictService coursePlanConflictService;
	@Autowired
	private CourseConflictService courseConflictService;
	
	@Override
	protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
		try {
			synchronized (this.isGennerStatus) {
				if (this.isGennerStatus) {
					return;
				} else {
					this.isGennerStatus = true;
				}
			}
			LambdaQueryWrapper<SysConfig> sysConfigCourseWrapper = new LambdaQueryWrapper<>();
			sysConfigCourseWrapper.eq(SysConfig::getParamKey, "t_course_plan_enable_conflict");
			List<SysConfig> tempList = sysConfigService.list(sysConfigCourseWrapper);
			SysConfig coplConflictEnable = tempList.get(0); // 排课计划-冲突策略
			
			sysConfigCourseWrapper = new LambdaQueryWrapper<>();
			sysConfigCourseWrapper.eq(SysConfig::getParamKey, "t_course_enable_conflict");
			tempList = sysConfigService.list(sysConfigCourseWrapper);
			SysConfig courConflictEnable = tempList.get(0); // 课程-冲突策略
			
			
			// 获取要生成的学年学期
			LambdaQueryWrapper<SysConfig> sysConfigLambdaQueryWrapper = new LambdaQueryWrapper<>();
			sysConfigLambdaQueryWrapper.eq(SysConfig::getParamKey, "current_genner_term_time");
			List<SysConfig> sysList = sysConfigService.list(sysConfigLambdaQueryWrapper);
			if (sysList == null || sysList.size() == 0) {
				log.info("系统配置：生成课程的学年学期（current_genner_term_time）没有配置值\n");
			} else {
				Long tetiId = Long.parseLong(sysList.get(0).getParamValue());
				TermTime termTime = this.termTimeService.getTermTimeById(tetiId);
				if (termTime == null) {
					log.info("系统配置：生成课程的学年学期（current_genner_term_time）配置的学年学期不存存\n");
				} else {
					// 获取学年学期对应的排课计划
					LambdaQueryWrapper<CoursePlan> queryWrapper = new LambdaQueryWrapper<>();
					queryWrapper.eq(CoursePlan::getTetiId, tetiId);
					List<Integer> gennerStatusList = Arrays.stream((new Integer[]{0, 1, 2, 3})).collect(Collectors.toList());
					queryWrapper.in(CoursePlan::getCoplCourseGennerStatus, gennerStatusList);
					List<CoursePlan> coursePlanList = coursePlanService.list(queryWrapper);
					
					// 排课计划【冲突情况-处理】
					if ("1".equals(coplConflictEnable.getParamValue())) {
						// 【配置策略】允许排课冲冲突情况，所以需要处理
						// 教员分身冲突-情况处理
						this.coursePlanConflictService.saveCpcoConflictProcess(DateUtil.beginOfDay(Calendar.getInstance().getTime()),
								DateUtil.endOfDay(termTime.getTetiTermEndDate()), CourseConstants.TEACHER_KEY, null);
						// 教室空间占用冲突-情况处理
						this.coursePlanConflictService.saveCpcoConflictProcess(DateUtil.beginOfDay(Calendar.getInstance().getTime()),
								DateUtil.endOfDay(termTime.getTetiTermEndDate()), CourseConstants.CLASS_ROOM_KEY, null);
					}
					
					// 生成课程冲突情况
					if (coursePlanList != null && coursePlanList.size() != 0) {
						// 排课计划预生成情况，批量写入课程生成情况
						for (CoursePlan coursePlan : coursePlanList) {
							this.coursePlanConflictService.saveTransCourseConflict(coplConflictEnable, coursePlan);
						}
					}
					
					// 课程冲突情况处理（排课计划和手动创建的课程可能有冲突）
					// 教员分身冲突-情况处理
					this.courseConflictService.saveCourConflictProcess(DateUtil.beginOfDay(Calendar.getInstance().getTime()),
							DateUtil.endOfDay(termTime.getTetiTermEndDate()), CourseConstants.TEACHER_KEY, null);
					// 教室空间占用冲突-情况处理
					this.courseConflictService.saveCourConflictProcess(DateUtil.beginOfDay(Calendar.getInstance().getTime()),
							DateUtil.endOfDay(termTime.getTetiTermEndDate()), CourseConstants.CLASS_ROOM_KEY, null);
					
					// 将课程生成情况(不冲突的数据)，写入单节课程
 					this.courseConflictService.saveBatchCourse(courConflictEnable, Calendar.getInstance().getTime(), termTime.getTetiTermEndDate());
					
				}
			}
		} catch (Exception e) {
			log.error("", e);
		} finally {
			synchronized (isGennerStatus) {
				this.isGennerStatus = false;
			}
		}
		
	}
}
